home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga CD-Sensation: Golden Games
/
Amiga CD-Sensation - Ausgabe 2 - Golden Games (1996)(GTI - Schatztruhe)(DE)[!].iso
/
Brain Activity
/
Conquest
/
Conquest.mod
< prev
next >
Wrap
Text File
|
1992-12-20
|
51KB
|
1,736 lines
MODULE Conquest;
IMPORT
DosD,DosL,
MLL:MathLibLong,
RN:RandomNumber,
Storage,
SYSTEM;
FROM Conquest2
IMPORT
ambCost,bdsize,board,battleShipCost,battleShipGuns,
bExploreProb,bExploreVar,blankLine,cExploreProb,cExploreVar,
colStars,cruiserCost,cruiserGuns,curRange,cursor,distance,
enemyArrival,enemyDepart,enemyResearch,gameOver,
growthRate,initgrowthenemy,initgrowthplayer,initmoney,
initrange,initunit,initvel,initweap,IntType,investCost,
iuRatio,left,Line,maxRange,maxVelocity,maxWeapons,
maxTurns,mbCost,min,nstars,Planet,PlanetPtr,playerArrival,
prodYear,rangeRequired,rangeResearch,rawFile,
RealStarList,resCostFactor,right,scoutCost,sExploreProb,
sExploreVar,Star,StarList,stars,TaskForce,Team,
tExploreProb,tExploreVar,tf,tfStars,turn,vel,
velocityRequired,velocityResearch,weaponRequired,
weaponResearch,weapons,
AnyWarShip,CheckGameOver,ClearField,ClearLeft,ClearScreen,
CursorOff,CursorOn,DisplayForces,DisplayTF,DoResearch,
EnemyAttack,ErrorMessage,FindBestPlan,GetChar,GetLine,
GetStars,GetTF,GetToken,Help,JoinSilent,JoinTF,Lose,MakeTF,
OnBoard,Pause,PlayerAttack,PrintColony,PrintMap,
PrintPlanet,PrintStar,PrintTF,PutCh,PutInt,PutStr,
ResearchSummary,Revolt,SetCursorPos,SetDestination,
StarSummary,TFBattle,TFSummary,UpdateBoard,WithDraw,ZeroTF;
VAR
vers: ARRAY[0..80] OF CHAR;
CONST
version="\o$VER: Conquest 2.3 (20-DEC-92) (PD) JOW\o";
PROCEDURE NextYear;
BEGIN
INC(turn);
INC(prodYear);
SetCursorPos(31,18);
PutStr(" Year ");
SetCursorPos(37,18);
PutInt(turn,3);
SetCursorPos(31,19);
PutStr(" Production year ");
SetCursorPos(48,19);
PutInt(prodYear,1);
END NextYear;
PROCEDURE NewPlanet(VAR x: PlanetPtr);
BEGIN
Storage.ALLOCATE(x,SIZE(Planet));
END NewPlanet;
PROCEDURE Battle;
VAR
first: BOOLEAN;
starnum: IntType;
BEGIN
first:=TRUE;
FOR starnum:=1 TO nstars DO
IF (tfStars[starnum][ENEMY]>0) AND
(tfStars[starnum][player]>0) AND
(AnyWarShip(ENEMY, starnum) OR AnyWarShip(player, starnum)) THEN
IF first THEN
SetCursorPos(32,20);
PutStr("* Taskforce battle *");
first:=FALSE;
END;
TFBattle(starnum);
END;
IF (AnyWarShip(ENEMY,starnum)) AND (colStars[starnum][player]>0) THEN
EnemyAttack(starnum);
ELSIF (tfStars[starnum][player]>0) AND (colStars[starnum][ENEMY]>0) THEN
PlayerAttack(starnum);
END;
END;
END Battle;
PROCEDURE BlastPlanet(VAR star: Star; planet: PlanetPtr; factors: IntType);
VAR
killed: IntType;
prev,curr: PlanetPtr;
done: BOOLEAN;
BEGIN
killed:=min(planet^.capacity,factors DIV 4);
planet^.inhabitants:=min(planet^.inhabitants,planet^.capacity)-killed;
planet^.iu:=min(planet^.iu-killed,planet^.inhabitants*iuRatio);
planet^.capacity:=planet^.capacity-killed;
IF planet^.inhabitants<=0 THEN
planet^.inhabitants:=0;
planet^.iu:=0;
planet^.mb:=0;
planet^.amb:=0;
IF planet^.team#none THEN
DEC(colStars[planet^.pstar][planet^.team]);
planet^.team:=none;
planet^.eSeeTeam:=none;
planet^.conquered:=FALSE;
OnBoard(stars[planet^.pstar].x,stars[planet^.pstar].y);
END;
IF planet^.capacity<=0 THEN
IF planet=star.firstPlanet THEN
star.firstPlanet:=planet^.next;
Storage.DEALLOCATE(planet,SIZE(Planet));
ELSE
prev:=star.firstPlanet;
curr:=star.firstPlanet^.next;
done:=FALSE;
REPEAT
IF curr=planet THEN
prev^.next:=curr^.next;
Storage.DEALLOCATE(curr,SIZE(Planet));
done:=TRUE;
ELSE;
prev:=curr;
curr:=curr^.next;
END;
UNTIL (curr=NIL) OR done;
END;
END;
END;
END BlastPlanet;
PROCEDURE AssignPlanets(VAR ustar: Star;
starnum: IntType;
psize: CHAR);
VAR
i1,nplanets: IntType;
pplanet: PlanetPtr;
BEGIN
nplanets:=RN.RND(2+((INTEGER(psize)-48+1) DIV 2));
IF (RN.RND(5)<=INTEGER(psize)-48) AND (nplanets>0) THEN
INC(nplanets);
END;
IF nplanets<=0 THEN
ustar.firstPlanet:=NIL;
ELSE
NewPlanet(pplanet);
ustar.firstPlanet:=pplanet;
FOR i1:=1 TO nplanets DO
pplanet^.number:=i1;
IF (RN.RND(10)>3) AND ((pplanet^.number>2) OR (nplanets=1)) THEN
CASE psize OF
|"1": pplanet^.capacity:=10*(RN.RND(5)+2);
|"2": pplanet^.capacity:=10*(RN.RND(10)+3);
|"3": pplanet^.capacity:=10*(RN.RND(13)+4);
|"4": pplanet^.capacity:=10*(RN.RND(14)+5);
|"5": pplanet^.capacity:=20*(RN.RND(15)+6);
END;
ELSE
CASE psize OF
|"1": pplanet^.capacity:=5*RN.RND(4)+5;
|"2": pplanet^.capacity:=5*RN.RND(6)+5;
|"3": pplanet^.capacity:=5*RN.RND(8)+10;
|"4": pplanet^.capacity:=5*RN.RND(10)+15;
|"5": pplanet^.capacity:=10*RN.RND(10)+20;
END;
END;
pplanet^.pSeeCapacity:=pplanet^.capacity;
pplanet^.team:=none;
pplanet^.inhabitants:=0;
pplanet^.iu:=0;
pplanet^.mb:=0;
pplanet^.amb:=0;
pplanet^.conquered:=FALSE;
pplanet^.underAttack:=FALSE;
pplanet^.eSeeTeam:=none;
pplanet^.eSeeDefend:=1;
pplanet^.pstar:=starnum;
IF i1=nplanets THEN
pplanet^.next:=NIL;
ELSE
NewPlanet(pplanet^.next);
pplanet:=pplanet^.next;
END;
END;
END;
END AssignPlanets;
PROCEDURE InitPlayer;
VAR
str,key: CHAR;
starNum: IntType;
balance,cost,amt,ind: IntType;
iline: Line;
BEGIN
REPEAT
SetCursorPos(1,18);
PutStr("start at star?\n ");
GetChar(str);
SetCursorPos(1,19);
starNum:=IntType(str)-IntType("A")+1;
UNTIL (starNum>=1) AND (starNum<=nstars);
tf[player][1].x:=stars[starNum].x;
tf[player][1].y:=stars[starNum].y;
tfStars[starNum][player]:=1;
tf[player][1].dest:=starNum;
SetCursorPos(1,20);
PutStr("choose your initial fleet.");
SetCursorPos(1,21);
PutStr("you have "); PutInt(initunit,0);
PutStr(" transports");
SetCursorPos(1,22);
PutStr(" and "); PutInt(initmoney,0);
PutStr(" units to spend");
SetCursorPos(1,23);
PutStr("on ships or research.");
balance:=initmoney;
ResearchSummary;
REPEAT
SetCursorPos(1,19);
PrintTF(1);
SetCursorPos(1,18);
PutInt(balance,3); PutStr("? ");
SetCursorPos(6,18);
GetLine(iline,ind,FALSE);
REPEAT
GetToken(iline,ind,amt,key);
CASE key OF
|"C": cost:=amt*cruiserCost;
IF cost<=balance THEN
tf[player][1].c:=tf[player][1].c+amt;
END;
|"S": cost:=amt*scoutCost;
IF cost<=balance THEN
tf[player][1].s:=tf[player][1].s+amt;
END;
|"B": cost:=amt*battleShipCost;
IF cost<=balance THEN
tf[player][1].b:=tf[player][1].b+amt;
END;
|"H": Help(0);
cost:=0;
|"W",
"V",
"R": cost:=amt;
IF cost<=balance THEN
DoResearch(player,key,amt);
END;
ResearchSummary;
|" ": cost:=0;
|">": SetCursorPos(1,18);
PutStr(">? ");
SetCursorPos(4,18);
cost:=0;
GetChar(key);
CASE key OF
|"M": PrintMap;
|"R": ResearchSummary;
|ELSE ErrorMessage;
PutStr(" !only M,R during initialize");
END;
|ELSE ErrorMessage;
PutStr( " !Illegal field "); PutCh(key);
END;
IF cost<=balance THEN
balance:=balance-cost;
ELSE
ErrorMessage();
PutStr(" !can't afford "); PutCh(key);
END;
UNTIL key=" ";
UNTIL balance<=0;
stars[starNum].visit[player]:=TRUE;
board[stars[starNum].x][stars[starNum].y].tf:='a';
board[stars[starNum].x][stars[starNum].y].enemy:=' ';
OnBoard(stars[starNum].x,stars[starNum].y);
SetCursorPos(32,20);
END InitPlayer;
PROCEDURE InitConstants;
VAR
i3,i1,i2,x,y,temp: IntType;
team: Team;
tt: CHAR;
date: DosD.Date;
ch: CHAR;
level: CHAR;
planetsize: CHAR;
randomEnemy: BOOLEAN;
BEGIN
PutStr("\n* Welcome to CONQUEST! *\n\n");
PutStr("Amiga version 2.3\n");
PutStr("Original author (UNIX) unknown\n");
PutStr("Original Amiga port by Bob Shimbo\n");
PutStr("Enhanced Amiga version by JOW (based on the release on Fish #24)\n\n");
PutStr("Original Copyright unknown, this version is PD (without restrictions)\n\n");
PutStr("level 1=easy, 2=medium, 3=hard (default=2)? ");
GetChar(level);
IF level#"\n" THEN
PutCh("\n");
END;
IF (level#"1") AND (level#"3") THEN
level:="2";
END;
DosL.DateStamp(SYSTEM.ADR(date));
RN.PutSeed(date.tick);
(* init the board *)
FOR i1:=1 TO bdsize DO
FOR i2:=1 TO bdsize DO
board[i1][i2].enemy:=" ";
board[i1][i2].tf:=" ";
board[i1][i2].star:=".";
END;
END;
PutStr("planet size 1=tiny 2=small 3=medium 4=large 5=giant (default=3)? ");
GetChar(planetsize);
IF planetsize#"\n" THEN
PutCh("\n");
END;
IF (planetsize#"1") AND (planetsize#"2") AND
(planetsize#"4") AND (planetsize#"5") THEN
planetsize:="3";
END;
(* init stars *)
FOR i1:=1 TO nstars DO
enemyArrival[i1]:=FALSE;
enemyDepart[i1]:=FALSE;
playerArrival[i1]:=FALSE;
REPEAT
x:=RN.RND(bdsize)+1;
y:=RN.RND(bdsize)+1;
UNTIL board[x][y].star=".";
stars[i1].x:=x;
stars[i1].y:=y;
FOR i2:=1 TO i1 DO
IF i1=i2 THEN
distance[i1][i2]:=0;
ELSE
temp:=((x-stars[i2].x)*(x-stars[i2].x))+
((y-stars[i2].y)*(y-stars[i2].y));
(* preset distance to boardsize*sqrt(2) *)
distance[i1][i2]:=(bdsize*15) DIV 10;
FOR i3:=1 TO (bdsize*15) DIV 10 DO
IF temp<i3*i3 THEN
distance[i1][i2]:=i3;
i3:=bdsize+bdsize; (* exit FOR loop *)
END;
END;
distance[i2][i1]:=distance[i1][i2];
END;
END;
FOR team:=ENEMY TO player DO
tfStars[i1][team]:=0;
colStars[i1][team]:=0;
END;
board[x][y].star:=CHAR(IntType("A")+i1-1);
board[x][y].enemy:="?";
stars[i1].visit[player]:=FALSE;
stars[i1].visit[ENEMY]:=FALSE;
AssignPlanets(stars[i1],i1,planetsize);
END;
(* initialize research costs *)
CASE level OF
|"1": rangeRequired[02]:=3;
|"2": rangeRequired[02]:=5;
|"3": rangeRequired[02]:=7;
END;
FOR i1:=3 TO maxRange DO
IF i1<=10 THEN
rangeRequired[i1]:=IntType(LONGREAL(rangeRequired[i1-1])*resCostFactor)+1;
ELSE
rangeRequired[i1]:=IntType(LONGREAL(rangeRequired[i1-1])*(resCostFactor-0.2))+1;
END;
IF rangeRequired[i1]>99 THEN
rangeRequired[i1]:=10*(rangeRequired[i1] DIV 10);
ELSIF rangeRequired[i1]>999 THEN
rangeRequired[i1]:=100*(rangeRequired[i1] DIV 100);
ELSIF rangeRequired[i1]>9999 THEN
rangeRequired[i1]:=1000*(rangeRequired[i1] DIV 1000);
END;
END;
CASE level OF
|"1": velocityRequired[02]:=30;
|"2": velocityRequired[02]:=40;
|"3": velocityRequired[02]:=50;
END;
FOR i1:=3 TO maxVelocity DO
IF i1<=10 THEN
velocityRequired[i1]:=IntType(LONGREAL(velocityRequired[i1-1])*resCostFactor)+1;
ELSE
velocityRequired[i1]:=IntType(LONGREAL(velocityRequired[i1-1])*resCostFactor-0.1)+1;
END;
IF velocityRequired[i1]>99 THEN
velocityRequired[i1]:=10*(velocityRequired[i1] DIV 10);
ELSIF velocityRequired[i1]>999 THEN
velocityRequired[i1]:=100*(velocityRequired[i1] DIV 100);
ELSIF velocityRequired[i1]>9999 THEN
velocityRequired[i1]:=1000*(velocityRequired[i1] DIV 1000);
END;
END;
CASE level OF
|"1": weaponRequired[2]:=15;
|"2": weaponRequired[2]:=20;
|"3": weaponRequired[2]:=25;
END;
FOR i1:=3 TO maxWeapons DO
IF i1<=10 THEN
weaponRequired[i1]:=IntType(LONGREAL(weaponRequired[i1-1])*(resCostFactor+0.2))+1;
ELSE
weaponRequired[i1]:=IntType(LONGREAL(weaponRequired[i1-1])*resCostFactor)+1;
END;
IF weaponRequired[i1]>99 THEN
weaponRequired[i1]:=10*(weaponRequired[i1] DIV 10);
ELSIF weaponRequired[i1]>999 THEN
weaponRequired[i1]:=100*(weaponRequired[i1] DIV 100);
ELSIF weaponRequired[i1]>9999 THEN
weaponRequired[i1]:=1000*(weaponRequired[i1] DIV 1000);
END;
END;
(* initialize task forces *)
tf[ENEMY][1].x:=1;
tf[ENEMY][1].y:=1;
FOR team:=ENEMY TO player DO
FOR i1:=1 TO 26 DO
tf[team][i1].dest:=0;
tf[team][i1].blasting:=FALSE;
tf[team][i1].withdrew:=FALSE;
tf[team][i1].s:=0;
tf[team][i1].t:=0;
tf[team][i1].c:=0;
tf[team][i1].b:=0;
tf[team][i1].dest:=0;
tf[team][i1].eta:=0;
END;
tf[team][1].t:=initunit+20-(INTEGER(level)-48)*10;
vel[team]:=initvel;
curRange[team]:=initrange;
weapons[team]:=initweap;
weaponResearch[team]:=0;
velocityResearch[team]:=0;
rangeResearch[team]:=0;
END;
INC(curRange[ENEMY],1+(INTEGER(level)-48));
growthRate[player]:=initgrowthplayer;
growthRate[ENEMY]:=initgrowthenemy;
IF level="3" THEN
INC(weapons[ENEMY]);
INC(vel[ENEMY]);
INC(tf[ENEMY][1].t,10);
growthRate[ENEMY]:=initgrowthenemy+0.1;
growthRate[player]:=initgrowthplayer-0.05;
END;
PutStr("randomize enemy (Y/n)? ");
GetChar(ch);
IF ch#"\n" THEN
PutCh("\n");
END;
randomEnemy:=(ch#"n") AND (ch#"N");
IF randomEnemy THEN
FOR i1:=1 TO 3 DO
CASE RN.RND(3) OF
|0: INC(weapons[ENEMY]);
|1: INC(vel[ENEMY]);
|2: growthRate[ENEMY]:=growthRate[ENEMY]+0.07;
END;
END;
END;
gameOver:=FALSE;
turn:=1;
prodYear:=1;
PrintMap();
SetCursorPos(32,20);
PutStr("* Initialization * ");
InitPlayer();
END InitConstants;
PROCEDURE InitMatch;
VAR
resAmount,maxx,startStar,starnum,count: IntType;
slist: RealStarList;
BEGIN
tf[ENEMY][1].c:=1;
tf[ENEMY][1].s:=2;
enemyResearch:="V";
resAmount:=2;
DoResearch(ENEMY,enemyResearch,resAmount);
maxx:=0;
startStar:=0;
FOR starnum:=1 TO nstars DO
GetStars(starnum,slist,count);
count:=count+RN.RND(5)+1;
IF count>maxx THEN
maxx:=count;
startStar:=starnum;
END;
END;
tf[ENEMY][1].dest:=startStar;
tf[ENEMY][1].x:=stars[startStar].x;
tf[ENEMY][1].y:=stars[startStar].y;
stars[startStar].visit[ENEMY]:=TRUE;
tfStars[startStar][ENEMY]:=1;
SetCursorPos(50,1);
PrintStar(tf[player][1].dest);
ClearField;
IF startStar=tf[player][1].dest THEN
ClearLeft;
Battle;
END;
END InitMatch;
PROCEDURE Depart(starnum: IntType);
BEGIN
IF (tfStars[starnum][player]+colStars[starnum][player])>0 THEN
enemyDepart[starnum]:=TRUE;
END;
END Depart;
PROCEDURE UnderDefPlanet(planet: PlanetPtr): BOOLEAN;
BEGIN
RETURN (planet^.iu>10) AND ((6*planet^.amb+planet^.mb)<(planet^.iu DIV 2));
END UnderDefPlanet;
PROCEDURE EvalBCColony(planet: PlanetPtr): IntType;
VAR
i,forces: IntType;
result: IntType;
BEGIN
IF NOT stars[planet^.pstar].visit[ENEMY] THEN
result:=300;
IF RN.RND(10)<2 THEN
result:=600;
END;
ELSE
CASE planet^.eSeeTeam OF
|none: result:=150+planet^.capacity*2;
|ENEMY: IF planet^.conquered THEN
result:=200+planet^.capacity*3;
ELSIF UnderDefPlanet(planet) THEN
result:=200+planet^.capacity*2;
ELSE
result:=0;
END;
|player: IF planet^.conquered THEN
result:=100+planet^.capacity*5;
ELSE
result:=100+planet^.capacity*4;
IF RN.RND(10)<2 THEN
result:=result*3;
END;
END;
END;
END;
result:=result+RN.RND(20)+1;
RETURN result;
END EvalBCColony;
PROCEDURE EvalTColony(planet: PlanetPtr; dist: LONGREAL): IntType;
VAR
result: IntType;
BEGIN
IF NOT stars[planet^.pstar].visit[ENEMY] THEN
result:=120;
ELSE
CASE planet^.eSeeTeam OF
|none: result:=planet^.capacity*4;
|ENEMY: result:=(planet^.capacity-planet^.inhabitants)*4;
|player: result:=-10000;
END;
END;
result:=result-IntType(dist+dist+0.5);
RETURN result;
END EvalTColony;
PROCEDURE WanderBC(VAR task: TaskForce; VAR slist: RealStarList);
VAR
ships,i,count,dest,newTF: IntType;
BEGIN
IF (task.b>1) OR (task.c>1) THEN
count:=0;
FOR i:=1 TO nstars DO
IF slist[i]#0.0 THEN
INC(count);
END;
END;
IF count>0 THEN
dest:=RN.RND(count)+1;
count:=0;
i:=0;
REPEAT
INC(i);
IF slist[i]>0.0 THEN
INC(count);
END;
UNTIL count=dest;
GetTF(ENEMY,newTF,task.dest);
ships:=task.b DIV 2;
tf[ENEMY][newTF].b:=ships;
task.b:=task.b-ships;
ships:=task.c DIV 2;
tf[ENEMY][newTF].c:=ships;
task.c:=task.c-ships;
IF task.t>3 THEN
ships:=task.t DIV 2;
tf[ENEMY][newTF].t:=ships;
task.t:=task.t-ships;
END;
tf[ENEMY][newTF].dest:=i;
tf[ENEMY][newTF].eta:=IntType((slist[i]-0.01) / LONGREAL(vel[ENEMY]))+1;
Depart(task.dest);
END;
END;
END WanderBC;
PROCEDURE MoveBC(VAR task: TaskForce; VAR slist: RealStarList);
VAR
bestStar,topScore,starnum,score,factors: IntType;
pplanet,bestPlanet: PlanetPtr;
BEGIN
IF (task.b>0) OR (task.c>0) THEN
FOR starnum:=1 TO nstars DO
IF slist[starnum]>0.0 THEN
bestStar:=starnum;
starnum:=nstars+1;
END;
END;
bestPlanet:=NIL;
topScore:=-1000;
FOR starnum:=1 TO nstars DO
IF (slist[starnum]>0.0) OR (starnum=task.dest) THEN
pplanet:=stars[starnum].firstPlanet;
WHILE pplanet#NIL DO
score:=EvalBCColony(pplanet);
IF starnum=task.dest THEN
score:=score+50;
END;
IF (tfStars[starnum][ENEMY]>0) AND (turn<50) THEN
score:=score-150;
END;
IF score>topScore THEN
topScore:=score;
bestPlanet:=pplanet;
bestStar:=starnum;
END;
pplanet:=pplanet^.next;
END;
END;
END;
IF bestStar=task.dest THEN
(* stay put *)
IF bestPlanet#NIL THEN
IF (bestPlanet^.team=ENEMY) AND (bestPlanet^.conquered) AND ((bestPlanet^.capacity<30) OR (bestPlanet^.capacity-bestPlanet^.iu>=30)) THEN
factors:=weapons[ENEMY]*(task.c*cruiserGuns+task.b*battleShipGuns);
factors:=min(factors,4*bestPlanet^.inhabitants);
BlastPlanet(stars[bestStar],bestPlanet,factors);
IF (tfStars[bestPlanet^.pstar][player]>0) OR (colStars[bestPlanet^.pstar][player]>0) THEN
bestPlanet^.pSeeCapacity:=bestPlanet^.capacity;
END;
ELSIF (bestPlanet^.team=ENEMY) AND (bestPlanet^.conquered) THEN
(* decide whether to split *)
IF (((task.b>3) OR (task.c>3)) AND (RN.RND(4)=3)) OR (task.b>8) THEN
WanderBC(task,slist);
END;
END;
END;
ELSE
(* move *)
DEC(tfStars[task.dest][ENEMY]);
Depart(task.dest);
task.dest:=bestStar;
task.eta:=IntType((slist[bestStar]-0.01)/LONGREAL(vel[ENEMY]))+1;
END;
END;
END MoveBC;
PROCEDURE SendTransTF(VAR task: TaskForce; VAR slist: RealStarList; destStar: IntType);
BEGIN
Depart(task.dest);
task.dest:=destStar;
task.eta:=IntType((slist[destStar]-0.01)/LONGREAL(vel[ENEMY]))+1;
END SendTransTF;
PROCEDURE UnderDefended(starnum: IntType): BOOLEAN;
VAR
pplanet: PlanetPtr;
result: BOOLEAN;
BEGIN
result:=FALSE;
pplanet:=stars[starnum].firstPlanet;
WHILE (pplanet#NIL) AND (NOT result) DO
result:=(pplanet^.team=ENEMY) AND UnderDefPlanet(pplanet);
pplanet:=pplanet^.next;
END;
RETURN(result);
END UnderDefended;
PROCEDURE Swap(VAR a,b: IntType);
VAR
t: IntType;
BEGIN
t:=a;
a:=b;
b:=t;
END Swap;
PROCEDURE SendTransports(VAR slist: RealStarList; VAR task: TaskForce);
VAR
newTF,toLand,secStar,secScore,bestStar,topScore,score,starnum: IntType;
xstar: IntType;
pplan,bestPlan: PlanetPtr;
trash1,trash2: IntType;
BEGIN
IF task.t>0 THEN
bestStar:=0;
secStar:=0;
secScore:=-11000;
topScore:=-10000;
bestPlan:=NIL;
FOR starnum:=1 TO nstars DO
IF (slist[starnum]>0.0) OR (starnum=task.dest) THEN
pplan:=stars[starnum].firstPlanet;
WHILE pplan#NIL DO
score:=EvalTColony(pplan,slist[starnum]);
xstar:=starnum;
IF score>topScore THEN
Swap(bestStar,xstar);
Swap(topScore,score);
bestPlan:=pplan;
END;
IF score>secScore THEN
secScore:=score;
secStar:=xstar;
END;
pplan:=pplan^.next;
END;
END;
END;
IF bestStar=task.dest THEN
(* land *)
IF (tfStars[bestStar][player]=0) AND (bestPlan^.team#player) THEN
trash1:=task.t;
trash2:=(bestPlan^.capacity-bestPlan^.inhabitants) DIV 3;
toLand:=min(trash1,trash2);
IF toLand>0 THEN
IF bestPlan^.inhabitants=0 THEN
bestPlan^.team:=ENEMY;
bestPlan^.eSeeTeam:=ENEMY;
INC(colStars[bestStar][ENEMY]);
END;
bestPlan^.inhabitants:=bestPlan^.inhabitants+toLand;
bestPlan^.iu:=bestPlan^.iu+toLand;
task.t:=task.t-toLand;
SendTransports(slist,task);
END;
END;
ELSE
(* move *)
IF (task.t>=10) AND (secStar>0) THEN
GetTF(ENEMY,newTF,task.dest);
tf[ENEMY][newTF].t:=task.t DIV 2;
task.t:=task.t-tf[ENEMY][newTF].t;
IF (task.c>0) AND (NOT UnderDefended(task.dest)) THEN
tf[ENEMY][newTF].c:=1;
DEC(task.c);
END;
SendTransTF(tf[ENEMY][newTF],slist,bestStar);
bestStar:=secStar;
END;
GetTF(ENEMY,newTF,task.dest);
tf[ENEMY][newTF].t:=task.t;
task.t:=0;
IF (task.c>0) AND (NOT UnderDefended(task.dest)) THEN
tf[ENEMY][newTF].c:=1;
DEC(task.c);
END;
SendTransTF(tf[ENEMY][newTF],slist,bestStar);
END;
END;
END SendTransports;
PROCEDURE SendScouts(VAR slist: RealStarList; VAR task: TaskForce);
VAR
dest,newTF,j,doind: IntType;
doable: StarList;
temp1,temp2: LONGREAL;
BEGIN
IF task.s>0 THEN
doind:=0;
FOR j:=1 TO nstars DO
IF (NOT stars[j].visit[ENEMY]) AND (slist[j]>0.0) THEN
INC(doind);
doable[doind]:=j;
END;
END;
WHILE (doind>0) AND (task.s>0) DO
GetTF(ENEMY,newTF,task.dest);
tf[ENEMY][newTF].s:=1;
dest:=RN.RND(doind)+1;
tf[ENEMY][newTF].dest:=doable[dest];
tf[ENEMY][newTF].eta:=IntType((slist[doable[dest]]-0.01)/LONGREAL(vel[ENEMY]))+1;
Depart(task.dest);
doable[dest]:=doable[doind];
DEC(doind);
DEC(task.s);
END;
WHILE task.s>0 DO
REPEAT
dest:=RN.RND(nstars)+1;
UNTIL slist[dest]>0.0;
GetTF(ENEMY,newTF,task.dest);
tf[ENEMY][newTF].s:=1;
tf[ENEMY][newTF].dest:=dest;
temp1:=slist[dest]-0.01;
temp2:=LONGREAL(vel[ENEMY]);
tf[ENEMY][newTF].eta:=IntType(temp1/temp2)+1;
Depart(task.dest);
DEC(task.s);
END;
END;
END SendScouts;
PROCEDURE InputMatch;
VAR
count,tfnum,starnum: IntType;
slist: RealStarList;
BEGIN
FOR tfnum:=1 TO 26 DO
IF (tf[ENEMY][tfnum].eta=0) AND (tf[ENEMY][tfnum].dest#0) THEN
starnum:=tf[ENEMY][tfnum].dest;
GetStars(starnum,slist,count);
SendScouts(slist,tf[ENEMY][tfnum]);
SendTransports(slist,tf[ENEMY][tfnum]);
MoveBC(tf[ENEMY][tfnum],slist);
ZeroTF(ENEMY,tfnum);
END;
END;
END InputMatch;
PROCEDURE MoveShips;
VAR
ratio,prob: LONGREAL;
there,dx,dy,i: IntType;
tm: Team;
pplanet: PlanetPtr;
any,loss: BOOLEAN;
BEGIN
(* clear the board *)
FOR i:=1 TO 26 DO
IF (tf[player][i].dest#0) AND (tf[player][i].eta#0) THEN
board[tf[player][i].x][tf[player][i].y].tf:=" ";
UpdateBoard(tf[player][i].x,tf[player][i].y,right);
END;
END;
(* move ships of both teams *)
tm:=ENEMY;
REPEAT
FOR i:=1 TO 26 DO
IF (tf[tm][i].dest#0) AND (tf[tm][i].eta#0) THEN
DEC(tf[tm][i].eta);
IF (NOT stars[tf[tm][i].dest].visit[tm]) AND (tf[tm][i].eta=0) AND (tm=player) THEN
ClearLeft();
SetCursorPos(1,19);
PutStr("Task force "); PutCh(CHAR(IntType("a")+i-1));
PutStr(" exploring "); PutCh(CHAR(tf[tm][i].dest+IntType("A")-1));
PutStr(".\n");
prob:=(tExploreProb+LONGREAL((RN.RND(tExploreVar)+1)*tf[tm][i].t))/100.0;
IF tf[tm][i].s#0 THEN
prob:=(sExploreProb+LONGREAL((RN.RND(sExploreVar)+1)*tf[tm][i].s))/100.0;
END;
IF tf[tm][i].c#0 THEN
prob:=(cExploreProb+LONGREAL((RN.RND(cExploreVar)+1)*tf[tm][i].c))/100.0;
END;
IF tf[tm][i].b#0 THEN
prob:=(bExploreProb+LONGREAL((RN.RND(bExploreVar)+1)*tf[tm][i].b))/100.0;
END;
IF prob>100.0 THEN
prob:=100.0;
END;
loss:=TRUE;
Lose(tf[tm][i].t,loss,"t",prob);
Lose(tf[tm][i].s,loss,"s",prob);
Lose(tf[tm][i].c,loss,"c",prob);
Lose(tf[tm][i].b,loss,"b",prob);
IF loss THEN
PutStr("No ships");
END;
PutStr(" destroyed.");
Pause;
tf[tm][i].eta:=1; (* fool zero tf *)
ZeroTF(tm,i);
tf[tm][i].eta:=0; (* fool zero tf *)
END;
IF tf[tm][i].dest#0 THEN
IF tm=player THEN
dx:=stars[tf[tm][i].dest].x;
dy:=stars[tf[tm][i].dest].y;
ratio:=1.0-LONGREAL(tf[tm][i].eta)/LONGREAL(tf[tm][i].origeta);
tf[tm][i].x:=tf[tm][i].xf+IntType(ratio*LONGREAL(dx-tf[tm][i].xf));
tf[tm][i].y:=tf[tm][i].yf+IntType(ratio*LONGREAL(dy-tf[tm][i].yf));
IF tf[tm][i].eta=0 THEN
pplanet:=stars[tf[tm][i].dest].firstPlanet;
WHILE pplanet#NIL DO
pplanet^.pSeeCapacity:=pplanet^.capacity;
pplanet:=pplanet^.next;
END;
playerArrival[tf[tm][i].dest]:=TRUE;
IF NOT stars[tf[tm][i].dest].visit[tm] THEN
board[tf[tm][i].x][tf[tm][i].y].enemy:=" ";
UpdateBoard(tf[tm][i].x,tf[tm][i].y,left);
stars[tf[tm][i].dest].visit[tm]:=TRUE;
END;
END;
END;
IF (tm=ENEMY) AND (tf[tm][i].eta=0) THEN
pplanet:=stars[tf[tm][i].dest].firstPlanet;
stars[tf[tm][i].dest].visit[ENEMY]:=TRUE;
WHILE pplanet#NIL DO
pplanet^.eSeeTeam:=pplanet^.team;
pplanet:=pplanet^.next;
END;
IF tfStars[tf[tm][i].dest][ENEMY]>0 THEN
there:=1;
WHILE (there=i) OR
(tf[ENEMY][there].dest#tf[ENEMY][i].dest) OR
(tf[ENEMY][there].eta#0) DO
INC(there);
END;
JoinSilent(ENEMY,tf[ENEMY][i],tf[ENEMY][there]);
END;
IF (tfStars[tf[tm][i].dest][player]>0) OR (colStars[tf[tm][i].dest][player]>0) THEN
enemyArrival[tf[tm][i].dest]:=TRUE;
END;
END;
IF tf[tm][i].eta=0 THEN
INC(tfStars[tf[tm][i].dest][tm]);
END;
END;
END;
END;
INC(tm);
UNTIL tm=none;
(* put the good guys on the board *)
FOR i:=1 TO 26 DO
IF tf[player][i].dest#0 THEN
tf[player][i].blasting:=FALSE;
dx:=tf[player][i].x;
dy:=tf[player][i].y;
IF board[dx][dy].tf=" " THEN
board[dx][dy].tf:=CHAR(i+IntType("a")-1);
ELSIF board[dx][dy].tf#CHAR(i+IntType("a")-1) THEN
board[dx][dy].tf:="*";
END;
UpdateBoard(dx,dy,right);
END;;
END;
any:=FALSE;
FOR i:=1 TO nstars DO
IF playerArrival[i] THEN
IF NOT any THEN
SetCursorPos(32,21);
PutStr("Player arrivals : ");
SetCursorPos(50,21);
any:=TRUE;
END;
PutCh(CHAR(i+IntType("A")-1));
playerArrival[i]:=FALSE;
END;
END;
IF NOT any THEN
SetCursorPos(32,21);
PutStr(blankLine);
END;
any:=FALSE;
FOR i:=1 TO nstars DO
IF enemyArrival[i] THEN
IF NOT any THEN
SetCursorPos(32,22);
PutStr("Enemy arrivals : ");
SetCursorPos(50,22);
any:=TRUE;
END;
PutCh(CHAR(i+IntType("A")-1));
enemyArrival[i]:=FALSE;
END;
END;
IF NOT any THEN
SetCursorPos(32,22);
PutStr(blankLine);
END;
any:=FALSE;
FOR i:=1 TO nstars DO
IF enemyDepart[i] THEN
IF NOT any THEN
SetCursorPos(32,23);
PutStr("Enemy departures: ");
SetCursorPos(50,23);
any:=TRUE;
END;
PutCh(CHAR(i+IntType("A")-1));
enemyDepart[i]:=FALSE;
END;
END;
IF NOT any THEN
SetCursorPos(32,23);
PutStr(blankLine);
END;
FOR i:=1 TO nstars DO
Revolt(i);
END;
END MoveShips;
PROCEDURE Blast;
VAR
tfCh,plCh: CHAR;
tfNum,planetNum: IntType;
pplanet: PlanetPtr;
factors,starnum: IntType;
done: BOOLEAN;
iline: Line;
ind,amount: IntType;
dum: CHAR;
BEGIN
PutStr("last");
ClearLeft();
SetCursorPos(1,19);
PutStr("Firing TF:");
GetChar(tfCh);
tfNum:=IntType(tfCh)-IntType("A")+1;
IF (tfNum<1) OR (tfNum>26) THEN
ErrorMessage();
PutStr(" !Illegal tf");
ELSIF tf[player][tfNum].dest=0 THEN
ErrorMessage();
PutStr(" !Nonexistant tf");
ELSIF tf[player][tfNum].eta#0 THEN
ErrorMessage();
PutStr(" !Tf is not in normal space ");
ELSIF tf[player][tfNum].blasting THEN
ErrorMessage();
PutStr(" !Tf is already blasting ");
ELSIF (tf[player][tfNum].b=0) AND (tf[player][tfNum].c=0) THEN
ErrorMessage();
PutStr(" !Tf has no warships ");
ELSE
starnum:=tf[player][tfNum].dest;
pplanet:=stars[starnum].firstPlanet;
IF pplanet=NIL THEN
ErrorMessage();
PutStr(" !No planets at star "); PutCh(CHAR(starnum+IntType("A")-1));
PutStr(" ");
ELSE
SetCursorPos(1,20);
PutStr("Target colony");
IF pplanet^.next=NIL THEN
PutInt(pplanet^.number,2);
ELSE
PutStr(": ");
GetChar(plCh);
planetNum:=IntType(plCh)-IntType("0");
REPEAT
IF pplanet^.number=planetNum THEN
done:=TRUE;
ELSE
IF pplanet^.next=NIL THEN
done:=TRUE;
ELSE
pplanet:=pplanet^.next;
done:=FALSE;
END;
END;
UNTIL done;
IF pplanet^.number#planetNum THEN
ErrorMessage();
PutStr(" !No such planet at this star ");
pplanet:=NIL;
END;
END;
IF pplanet#NIL THEN
IF pplanet^.team=ENEMY THEN
ErrorMessage();
PutStr(" !conquer it first!");
ELSIF (pplanet^.team=player) AND (NOT pplanet^.conquered) THEN
ErrorMessage();
PutStr(" !it's a human colony ");
ELSE
factors:=weapons[player]*((tf[player][tfNum].c*cruiserGuns)+(tf[player][tfNum].b*battleShipGuns));
SetCursorPos(1,21);
PutStr("Units (max "); PutInt(factors DIV 4,0); PutStr("): ");
(*
SetCursorPos(19,21);
*)
GetLine(iline,ind,FALSE);
GetToken(iline,ind,amount,dum);
IF amount<0 THEN
factors:=0;
ELSIF amount>0 THEN
factors:=min(factors,amount*4);
END;
tf[player][tfNum].blasting:=TRUE;
SetCursorPos(1,22);
PutStr("Blasting "); PutInt(factors DIV 4,0); PutStr(" units");
BlastPlanet(stars[starnum],pplanet,factors);
SetCursorPos(1,23);
PutCh(CHAR(pplanet^.pstar+IntType("A")-1));
pplanet^.pSeeCapacity:=pplanet^.capacity;
PrintPlanet(pplanet,TRUE);
END;
END;
END;
END;
END Blast;
PROCEDURE LandTransports;
VAR
tfc,trc,planc: CHAR;
x,y,roomLeft,tfnum,transports,planetNum: IntType;
starnum,ind: IntType;
iline: Line;
found: BOOLEAN;
pplanet: PlanetPtr;
BEGIN
PutStr("and tf:");
GetChar(tfc);
ClearLeft();
tfnum:=IntType(tfc)-IntType("A")+1;
IF (tfnum<1) OR (tfnum>26) THEN
ErrorMessage();
PutStr(" !illegal tf");
ELSIF tf[player][tfnum].dest=0 THEN
ErrorMessage();
PutStr(" !nonexistent tf");
ELSIF tf[player][tfnum].eta#0 THEN
ErrorMessage();
PutStr(" !tf is not in normal space ");
ELSE
starnum:=tf[player][tfnum].dest;
pplanet:=stars[starnum].firstPlanet;
IF pplanet=NIL THEN
ErrorMessage();
PutStr(" !no planets at this star ");
ELSIF tfStars[starnum][ENEMY]>0 THEN
ErrorMessage();
PutStr(" !enemy ships present");
ELSE
SetCursorPos(11,18);
PutStr(" planet ");
IF pplanet^.next=NIL THEN
planetNum:=pplanet^.number;
PutInt(planetNum,1);
ELSE
PutStr(":");
GetChar(planc);
planetNum:=IntType(planc)-IntType("0");
found:=FALSE;
WHILE (pplanet#NIL) AND (NOT found) DO
IF pplanet^.number=planetNum THEN
found:=TRUE;
ELSE
pplanet:=pplanet^.next;
END;
END;
IF NOT found THEN
planetNum:=0;
ErrorMessage();
PutStr(" !Not a habitable planet ");
END;
END;
IF planetNum#0 THEN
IF (pplanet^.team=ENEMY) OR ((pplanet^.team=player) AND (pplanet^.conquered)) THEN
ErrorMessage();
PutStr(" !Enemy colony on the planet ");
ELSE
(* get the number of transports *)
roomLeft:=pplanet^.capacity-pplanet^.inhabitants;
SetCursorPos(1,19);
PutStr(" transports:");
GetLine(iline,ind,FALSE);
GetToken(iline,ind,transports,trc);
IF transports=0 THEN
transports:=tf[player][tfnum].t;
END;
IF transports<1 THEN
ErrorMessage();
PutStr(" !illegal transports");
ELSIF transports>tf[player][tfnum].t THEN
ErrorMessage();
PutStr(" !only "); PutInt(tf[player][tfnum].t,0);
PutStr(" transports in tf");
ELSIF transports>roomLeft THEN
ErrorMessage();
PutStr(" !only room for "); PutInt(roomLeft,0);
PutStr(" transports");
ELSE
pplanet^.team:=player;
IF pplanet^.inhabitants=0 THEN
INC(colStars[starnum][player]);
END;
pplanet^.inhabitants:=pplanet^.inhabitants+transports;
pplanet^.iu:=pplanet^.iu+transports;
tf[player][tfnum].t:=tf[player][tfnum].t-transports;
x:=tf[player][tfnum].x;
y:=tf[player][tfnum].y;
IF board[x][y].enemy=" " THEN
board[x][y].enemy:="@";
UpdateBoard(x,y,left);
END;
SetCursorPos(1,20);
PutCh(CHAR(starnum+IntType("A")-1));
PrintPlanet(pplanet,TRUE);
ZeroTF(player,tfnum);
PrintTF(tfnum);
END;
END;
END;
END;
END;
END LandTransports;
PROCEDURE SendTF;
VAR
tfCh: CHAR;
tfNum: IntType;
error: BOOLEAN;
BEGIN
PutStr("estination tf: ");
GetChar(tfCh);
ClearLeft();
SetCursorPos(1,19);
tfNum:=IntType(tfCh)-IntType("A")+1;
IF (tfNum<1) OR (tfNum>26) THEN
ErrorMessage();
PutStr(" !illegal tf");
ELSIF tf[player][tfNum].dest=0 THEN
ErrorMessage();
PutStr(" !nonexistent tf");
ELSIF (tf[player][tfNum].eta#0) AND
((tf[player][tfNum].eta#tf[player][tfNum].origeta) OR tf[player][tfNum].withdrew) THEN
ErrorMessage();
PutStr(" !tf is not in normal space ");
ELSIF tf[player][tfNum].blasting THEN
ErrorMessage();
PutStr(" !tf is blasting a planet");
ELSE
tf[player][tfNum].withdrew:=FALSE;
SetDestination(tfNum,error);
END;
END SendTF;
PROCEDURE QuitGame;
VAR
answer: CHAR;
BEGIN
ClearScreen;
PutStr("Quit game... are you sure (y/N)? ");
GetChar(answer);
IF answer#"Y" THEN
PrintMap;
ELSE
gameOver:=TRUE;
END;
END QuitGame;
PROCEDURE InputPlayer;
VAR
key: CHAR;
fin: BOOLEAN;
BEGIN
SetCursorPos(32,20);
PutStr("* Movement * ");
fin:=FALSE;
REPEAT
SetCursorPos(1,18);
PutStr("? ");
SetCursorPos(3,18);
GetChar(key);
CASE key OF
|"M": PrintMap;
|"B": Blast;
|"G",
" ": fin:=TRUE;
|"H": Help(1);
|"L": LandTransports;
|"D": SendTF();
|"S": StarSummary();
|"N": MakeTF;
|"J": JoinTF();
|"C": PrintColony();
|"R": ResearchSummary();
|"Q": fin:=TRUE;
QuitGame;
|"?":
|"T": TFSummary();
|ELSE ErrorMessage();
PutStr(" !illegal command");
END;
UNTIL fin;
END InputPlayer;
PROCEDURE InvestEnemy(x,y: IntType; planet: PlanetPtr);
VAR
num,invAmount,balance,minMB,transports,newTF: IntType;
trash1,trash2: IntType;
BEGIN
balance:=planet^.iu;
IF tfStars[planet^.pstar][ENEMY]=0 THEN
GetTF(ENEMY,newTF,planet^.pstar);
tfStars[planet^.pstar][ENEMY]:=1;
ELSE
(* use present tf *)
newTF:=1;
WHILE (tf[ENEMY][newTF].dest#planet^.pstar) OR (tf[ENEMY][newTF].eta#0) DO
INC(newTF);
END;
END;
minMB:=planet^.capacity DIV 20;
WHILE (planet^.amb=0) AND (NOT planet^.conquered) AND (planet^.mb<minMB) AND (balance>=mbCost) AND (balance<ambCost) DO
balance:=balance-mbCost;
INC(planet^.mb);
END;
WHILE (balance>=battleShipCost) AND (RN.RND(5)>1) AND (NOT UnderDefPlanet(planet)) DO
balance:=balance-battleShipCost;
INC(tf[ENEMY][newTF].b);
END;
WHILE (balance>=ambCost) AND UnderDefPlanet(planet) AND (NOT planet^.conquered) DO
balance:=balance-ambCost;
INC(planet^.amb);
END;
WHILE balance>=9 DO
CASE RN.RND(15) OF
|1,2,
3,4: DoResearch(ENEMY,enemyResearch,9);
balance:=balance-9;
|5: IF balance>=cruiserCost THEN
balance:=balance-cruiserCost;
INC(tf[ENEMY][newTF].c);
ELSIF (NOT planet^.conquered) AND (balance>=mbCost) THEN
balance:=balance-mbCost;
INC(planet^.mb);
ELSE
balance:=balance-9;
DoResearch(ENEMY,enemyResearch,9);
END;
|6,7,
8: IF ((planet^.inhabitants DIV planet^.capacity>=1) AND
(planet^.inhabitants<IntType(LONGREAL(planet^.capacity)*growthRate[planet^.team])-1) AND
(NOT planet^.conquered))
OR
(NOT ((LONGREAL(planet^.inhabitants)/LONGREAL(planet^.capacity)<0.6) OR (planet^.capacity*iuRatio>=battleShipCost)))
OR
((planet^.iu<battleShipCost) AND (planet^.capacity<battleShipCost) AND (RN.RND(10)<7))
OR
((turn<100) AND (RN.RND(10)<8))
THEN
(* build transports *)
transports:=min(balance,planet^.inhabitants-planet^.capacity+1);
IF transports<0 THEN
transports:=min(4+RN.RND(5),planet^.inhabitants DIV 2);
END;
balance:=balance-transports;
planet^.inhabitants:=planet^.inhabitants-transports;
trash1:=planet^.iu-transports;
trash2:=planet^.inhabitants*iuRatio;
planet^.iu:=min(trash1,trash2);
tf[ENEMY][newTF].t:=tf[ENEMY][newTF].t+transports;
ELSE
(* no transports *)
WHILE (balance>=9) AND (planet^.inhabitants*iuRatio-planet^.iu>0) DO
invAmount:=min(3,planet^.inhabitants*iuRatio-planet^.iu);
balance:=balance-invAmount*investCost;
planet^.iu:=planet^.iu+invAmount;
END;
END;
|9: IF RN.RND(10)<5 THEN
balance:=balance-scoutCost;
INC(tf[ENEMY][newTF].s);
ELSE
DoResearch(ENEMY,enemyResearch,9);
balance:=balance-9;
END;
|ELSE invAmount:=min(3,planet^.inhabitants*iuRatio-planet^.iu);
balance:=balance-investCost*invAmount;
planet^.iu:=planet^.iu+invAmount;
END;
END;
ZeroTF(ENEMY,newTF);
DoResearch(ENEMY,enemyResearch,balance);
END InvestEnemy;
PROCEDURE InvestPlayer(x,y: IntType; planet: PlanetPtr);
VAR
printTaskForce: BOOLEAN;
iline: Line;
key: CHAR;
cost,amount,ind,newTF,balance: IntType;
trash1,trash2: IntType;
BEGIN
GetTF(player,newTF,planet^.pstar);
INC(tfStars[planet^.pstar][player]);
printTaskForce:=FALSE;
balance:=planet^.iu;
ClearLeft();
SetCursorPos(1,19);
PutCh(CHAR(planet^.pstar+IntType("A")-1));
PrintPlanet(planet,TRUE);
REPEAT
SetCursorPos(1,18);
PutInt(balance,3); PutStr("? ");
SetCursorPos(6,18);
GetLine(iline,ind,FALSE);
REPEAT
GetToken(iline,ind,amount,key);
CASE key OF
|"A": cost:=amount*ambCost;
IF planet^.inhabitants=0 THEN
cost:=0;
ErrorMessage();
PutStr(" !abandoned planet");
ELSIF planet^.conquered THEN
cost:=0;
ErrorMessage();
PutStr(" !No amb on conquered colony ");
ELSE
IF cost<=balance THEN
planet^.amb:=planet^.amb+amount;
END;
END;
|"B": cost:=amount*battleShipCost;
IF cost<=balance THEN
tf[player][newTF].b:=tf[player][newTF].b+amount;
printTaskForce:=TRUE;
END;
|"C": cost:=amount*cruiserCost;
IF cost<=balance THEN
tf[player][newTF].c:=tf[player][newTF].c+amount;
printTaskForce:=TRUE;
END;
|"H": Help(4);
cost:=0;
|"M": cost:=amount*mbCost;
IF planet^.inhabitants=0 THEN
cost:=0;
ErrorMessage();
PutStr(" !abandoned planet");
ELSIF planet^.conquered THEN
cost:=0;
ErrorMessage();
PutStr(" !no mb on conquered colony ");
ELSE
IF cost<=balance THEN
planet^.mb:=planet^.mb+amount;
END;
END;
|"S": cost:=amount*scoutCost;
IF cost<=balance THEN
tf[player][newTF].s:=tf[player][newTF].s+amount;
printTaskForce:=TRUE;
END;
|"T": cost:=amount;
IF cost<=balance THEN
IF cost>planet^.inhabitants THEN
ErrorMessage();
PutStr(" !not enough people for trans");
cost:=0;
ELSIF planet^.conquered THEN
cost:=0;
ErrorMessage();
PutStr(" !No transp. on conqered col.");
ELSE
tf[player][newTF].t:=tf[player][newTF].t+amount;
planet^.inhabitants:=planet^.inhabitants-amount;
trash1:=planet^.iu-amount;
trash2:=planet^.inhabitants*iuRatio;
planet^.iu:=min(trash1,trash2);
printTaskForce:=TRUE;
IF planet^.inhabitants=0 THEN
DEC(colStars[planet^.pstar][player]);
IF colStars[planet^.pstar][player]=0 THEN
board[x][y].enemy:=" ";
UpdateBoard(x,y,left);
END;
planet^.team:=none;
planet^.amb:=0;
planet^.mb:=0;
planet^.iu:=0;
END;
END;
END;
|"I": cost:=investCost*amount;
IF (amount+planet^.iu)>(planet^.inhabitants*iuRatio) THEN
cost:=0;
ErrorMessage();
PutStr(" !Can't support that many iu's");
ELSIF cost<=balance THEN
planet^.iu:=planet^.iu+amount;
END;
|"R",
"V",
"W": cost:=amount;
IF cost<=balance THEN
SetCursorPos(1,21);
DoResearch(player,key,amount);
END;
ResearchSummary;
|" ": cost:=0;
|">": cost:=0;
SetCursorPos(1,18);
PutStr(">? ");
SetCursorPos(4,18);
GetChar(key);
CASE key OF
|"M": PrintMap();
|"S": StarSummary();
|"C": PrintColony();
|"R": ResearchSummary();
|ELSE ErrorMessage();
PutStr(" !only M,S,C,R allowed ");
END;
|ELSE ErrorMessage();
PutStr(" !illegal field "); PutCh(key);
END;
IF cost>balance THEN
ErrorMessage();
PutStr(" !can't afford "); PutInt(amount,0); PutCh(key);
ELSE
balance:=balance-cost;
END;
UNTIL key=" ";
ClearLeft();
SetCursorPos(1,19);
PutCh(CHAR(planet^.pstar+IntType("A")-1));
PrintPlanet(planet,TRUE);
IF printTaskForce THEN
SetCursorPos(1,20);
PrintTF(newTF);
END;
UNTIL balance<=0;
ZeroTF(player,newTF);
OnBoard(x,y);
END InvestPlayer;
PROCEDURE Invest;
VAR
newborn,starnum: IntType;
pplan: PlanetPtr;
BEGIN
prodYear:=0;
SetCursorPos(32,20);
PutStr("* investment * ");
FOR starnum:=1 TO nstars DO
pplan:=stars[starnum].firstPlanet;
WHILE pplan#NIL DO
IF (pplan^.eSeeTeam=player) AND (pplan^.capacity>10) AND (pplan^.eSeeDefend<12) THEN
INC(pplan^.eSeeDefend);
END;
IF pplan^.team#none THEN
IF pplan^.inhabitants<pplan^.capacity THEN
newborn:=IntType(LONGREAL(pplan^.inhabitants)*growthRate[pplan^.team]+0.9);
ELSE
newborn:=0;
END;
IF pplan^.conquered THEN
newborn:=newborn DIV 2;
END;
pplan^.inhabitants:=pplan^.inhabitants+newborn;
pplan^.iu:=pplan^.iu+newborn;
IF pplan^.team=ENEMY THEN
InvestEnemy(stars[starnum].x,stars[starnum].y,pplan);
ELSE
InvestPlayer(stars[starnum].x,stars[starnum].y,pplan);
END;
END;
pplan:=pplan^.next;
END;
END;
Battle;
END Invest;
BEGIN
vers:=version;
rawFile:=DosL.Open(SYSTEM.ADR("RAW:0/0/1000/800/CONQUEST 2.3 by JOW"),DosD.newFile);
IF rawFile=NIL THEN
rawFile:=DosL.Open(SYSTEM.ADR("RAW:0/0/640/512/CONQUEST 2.3 by JOW"),DosD.newFile);
END;
IF rawFile=NIL THEN
rawFile:=DosL.Open(SYSTEM.ADR("RAW:0/0/600/380/CONQUEST 2.3 by JOW"),DosD.newFile);
END;
IF rawFile=NIL THEN
rawFile:=DosL.Open(SYSTEM.ADR("RAW:0/0/600/180/CONQUEST 2.3 by JOW"),DosD.newFile);
END;
IF rawFile=NIL THEN
rawFile:=DosL.Open(SYSTEM.ADR("RAW:0/0/300/100/CONQUEST 2.3 by JOW"),DosD.newFile);
END;
IF rawFile=NIL THEN
rawFile:=DosL.Open(SYSTEM.ADR("RAW:0/0/150/100/CONQUEST 2.3 by JOW"),DosD.newFile);
END;
IF rawFile#NIL THEN
CursorOff;
PutStr("\n *** CONQUEST V2.3 *** \n");
InitConstants;
InitMatch;
REPEAT
InputPlayer;
IF NOT gameOver THEN
InputMatch;
MoveShips;
Battle;
IF (prodYear=4) AND (turn<maxTurns) THEN
Invest;
END;
NextYear;
END;
CheckGameOver();
UNTIL gameOver;
Pause;
CursorOn;
END;
CLOSE
IF rawFile#NIL THEN
DosL.Close(rawFile);
END;
END Conquest.